﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Diagnostics;

namespace AdflyBot
{
    public partial class MainForm : Form
    {
        int IPsPerBot = 14;
        int numberOfAdflyLinks;
        int BotNumber;
        bool pausedBot = false;
        IDisposable ChangeLinkInterval;
        int linkInterval = 11000; //11 seconds
        int totalClicks = 0;
        int totalToClick = 0;
        HtmlElement htmlElement;

        //--- For Results ---

        string startTime;
        string endTime;

        //-------------------

        List<string> listOfIPs = new List<string>();
        List<string> listOfAdflyLinks = new List<string>();

        List<string> listOfIPsForBot = new List<string>();

        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            //Hide progress to make it look better
            lblProgress.Text = "";

            //Set max on bot number (ceil(number of IP's / IPsPerBot))
            string linkToListOfIPs = "http://www.squiblo.co.uk/AdflyBot/listOfIPs.xml";

            //Get list of IP's
            XmlDocument XMLlistOfIPs = new XmlDocument();
            XMLlistOfIPs.Load(linkToListOfIPs);

            //Populate listOfIPs
            foreach (XmlNode IP in XMLlistOfIPs.DocumentElement.ChildNodes)
            {
                listOfIPs.Add(IP.InnerText);
            }


            // ####################################################################


            //Get list of Adfly links
            string linkToListOfAdflyLinks = "http://www.squiblo.co.uk/AdflyBot/listOfAdflyLinks.xml";

            XmlDocument XMLlistOfAdflyLinks = new XmlDocument();
            XMLlistOfAdflyLinks.Load(linkToListOfAdflyLinks);

            //Populate listOfAdflyLinks
            foreach (XmlNode IP in XMLlistOfAdflyLinks.DocumentElement.ChildNodes)
            {
                listOfAdflyLinks.Add(IP.InnerText);
            }

            numberOfAdflyLinks = listOfAdflyLinks.Count();

            // ####################################################################

            
            //Set max for bot number
            decimal IPsPerBot_Decimals = Convert.ToDecimal(listOfIPs.Count()) / IPsPerBot;
            int maxBots = Convert.ToInt32(Math.Ceiling(IPsPerBot_Decimals));
            numericBotNumber.Maximum = maxBots;
            lblMaxBots.Text = "/" + maxBots;
            
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            if (lblMaxBots.Text != "...")
            {
                startTime = DateTime.Now.ToString("HH:mm:ss");

                BotNumber = Convert.ToInt32(numericBotNumber.Value);

                //Change Form Text
                if (pausedBot == true)
                    this.Text = "AdflyBot #" + BotNumber + " - Running";
                else
                    this.Text = "AdflyBot #" + BotNumber + " - Loading...";

                //Change buttons
                btnStart.Enabled = false;
                btnPause.Enabled = true;
                btnStop.Enabled = true;

                //Change labels
                if (pausedBot == true)
                {
                    lblStatus.ForeColor = Color.Green;
                    lblStatus.Text = "Running";
                }
                else
                {
                    lblStatus.ForeColor = Color.Black;
                    lblStatus.Text = "Loading...";
                }

                //Disable numericBotNumber
                numericBotNumber.Enabled = false;

                //Set Total Progress Number
                //Get List of IP's for this bot
                if (BotNumber != numericBotNumber.Maximum)
                {
                    totalToClick = IPsPerBot * numberOfAdflyLinks;
                    lblProgress.Text = "0/" + totalToClick;

                    int startIPsFrom = (BotNumber - 1) * IPsPerBot;

                    for (int i = startIPsFrom; i < startIPsFrom + IPsPerBot; i++)
                    {
                        listOfIPsForBot.Add(listOfIPs[i]);
                    }
                }
                else
                {
                    //Figure out how many remaining IP's
                    int remainingIps = listOfIPs.Count() % IPsPerBot;
                    totalToClick = remainingIps * numberOfAdflyLinks;
                    lblProgress.Text = "0/" + totalToClick;

                    int startIPsFrom = (BotNumber - 1) * IPsPerBot;

                    for (int i = startIPsFrom; i < startIPsFrom + remainingIps; i++)
                    {
                        listOfIPsForBot.Add(listOfIPs[i]);
                    }

                }

                pausedBot = false;
                RunAdflyBot();
            }
            else
            {
                MessageBox.Show("Unable to retrieve links. Check internet connection and XML host.", "AdflyBot - Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }


        }

        private void btnPause_Click(object sender, EventArgs e)
        {
            pausedBot = true;

            //Change Form Text
            this.Text = "AdflyBot #" + BotNumber + " - Paused";
            
            //Change Buttons
            btnStart.Enabled = true;
            btnPause.Enabled = false;
            btnStop.Enabled = true;

            //Change Labels
            lblStatus.ForeColor = Color.Black;
            lblStatus.Text = "Paused";
        }

        private void btnStop_Click(object sender, EventArgs e)
        {

            pausedBot = false;

            //Change Form Text
            this.Text = "AdflyBot #" + BotNumber + " - Stopped";

            //Change Buttons
            btnStart.Enabled = true;
            btnPause.Enabled = false;
            btnStop.Enabled = false;

            //Change Labels
            lblStatus.ForeColor = Color.DarkRed;
            lblStatus.Text = "Stopped";

            lblProgress.Text = "";

            lblIP.Text = "N/a";
            lblAdflyLink.Text = "N/a";

            //Enable numericBotNumber
            numericBotNumber.Enabled = true;

            //Change Progress
            lblProgress.Text = "";

            //Stop Invertal
            ChangeLinkInterval.Dispose();


            //Show final results
            endTime = DateTime.Now.ToString("HH:mm:ss");
            ResultsForm rF = new ResultsForm(BotNumber, startTime, endTime, totalClicks);
            rF.ShowDialog();
        }

        private void RunAdflyBot()
        {

            int adflyLinkIndex = 0;
            int ipIndex = 0;

            ChangeLinkInterval = EasyTimer.SetInterval(() =>
            {
                if (pausedBot == false)
                {
                    //Click Skip
                    if (totalClicks != 0)
                    {
                        pausedBot = true;

                        //clear cookies
                        browser.Invoke((Action)(() => browser.Navigate("javascript:void((function(){var a,b,c,e,f;f=0;a=document.cookie.split('; ');for(e=0;e<a.length&&a[e];e++){f++;for(b='.'+location.host;b;b=b.replace(/^(?:%5C.|[^%5C.]+)/,'')){for(c=location.pathname;c;c=c.replace(/.$/,'')){document.cookie=(a[e]+'; domain='+b+'; path='+c+'; expires='+new Date((new Date()).getTime()-1e11).toGMTString());}}}})())")));

                        //skip ad

                        browser.Invoke((Action)(() => this.htmlElement = browser.Document.GetElementById("skip_ad_button")));

                        if (this.htmlElement != null)
                        {
                            browser.Invoke((Action)(() => browser.ClickSkip()));
                            browser.Invoke((Action)(() => browser.Document.GetElementById("skip_ad_button").InvokeMember("click")));
                        }
                            

                        System.Threading.Thread.Sleep(1000); //sleep for 1 second
                        

                        pausedBot = false;
                    }


                    //--- Note: Every 5 adfly links, it changes account

                    //ChangeRunning labels
                    this.Invoke((Action)(() => this.Text = "AdflyBot #" + BotNumber + " - Running"));
                    lblStatus.Invoke((Action)(() => lblStatus.ForeColor = Color.Green));
                    lblStatus.Invoke((Action)(() => lblStatus.Text = "Running"));


                    //Display IP and Link on form
                    string ip = listOfIPsForBot[ipIndex];
                    lblIP.Invoke((Action)(() => lblIP.Text = ip));

                    string adflyLink = listOfAdflyLinks[adflyLinkIndex];
                    lblAdflyLink.Invoke((Action)(() => lblAdflyLink.Text = "/" + adflyLink.Replace("http://www.adf.ly/", "")));

                    //Set Proxy
                    CustomProxy.SetConnectionProxy(ip);

                    EditHeaders eH = new EditHeaders();

                    string randomUserAgent = eH.UserAgent();

                    //Go to Adfly Link
                    browser.Navigate("http://www.squiblo.co.uk/?l=" + adflyLink, null, null, "User-Agent: " + randomUserAgent + "\r\nCache-Control: no-store, no-cache, must-revalidate\r\n");

                    //Change progrss
                    totalClicks++;
                    lblProgress.Invoke((Action)(() => lblProgress.Text = totalClicks + "/" + totalToClick));
                    
                    if (adflyLinkIndex < listOfAdflyLinks.Count() - 1)
                    {
                        adflyLinkIndex++; //next link
                    }
                    else
                    {
                        adflyLinkIndex = 0; //start from the beginning

                        //Next ip address
                        if (ipIndex < listOfIPsForBot.Count() - 1)
                        {
                            ipIndex++; //Next ip address
                        }
                        else
                        {
                            ipIndex = 0; //Clicked all links with all IP's

                            //Stop Running Bot
                            lblIP.Invoke((Action)(() => btnStop.PerformClick()));  
                        }
                    }
 
                }
            }, linkInterval);
        }

    }

    public static class SkipAd
    {
        public static void ClickSkip(this WebBrowser wb)
        {
            wb.Document.InvokeScript("adf_skipButton");
        }
    }
}
